home *** CD-ROM | disk | FTP | other *** search
- Subject: v22i044: NN Newsreader, release 6.4, Part09/21
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: f84a93fc 2d9efbad e2cb911b 660525b3
-
- Submitted-by: "Kim F. Storm" <storm@texas.dk>
- Posting-number: Volume 22, Issue 44
- Archive-name: nn6.4/part09
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: doc/INSTALLATION man/nnacct.1m more.c
- # Wrapped by storm@texas.dk on Sun May 6 18:19:38 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 9 (of 22)."'
- if test -f 'doc/INSTALLATION' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'doc/INSTALLATION'\"
- else
- echo shar: Extracting \"'doc/INSTALLATION'\" \(23184 characters\)
- sed "s/^X//" >'doc/INSTALLATION' <<'END_OF_FILE'
- X CONFIGURATION AND INSTALLATION OF NN
- X ------------------------------------
- X
- X RELEASE 6.4
- X
- X
- XThis file describes the necessary steps to configure and install nn.
- XYou are advised to read this file before proceeding with the installation.
- X
- XNOTE: The configuration and installation has changed significantly
- X===== from previous releases, so read these instructions carefully
- X even if you are familiar with previous releases of nn.
- X
- XIf you want to use NNTP (accessing news from a remote host), you must
- Xalso read the file NNTP.
- X
- XThe files RELEASE_NOTES and PROBLEMS contains descriptions of problems
- Xpreviously seen when installing nn. If you run into a problem, consult
- Xthat file before griping about it.
- X
- XThe following command line prompts are used in the examples:
- X `$' is used when no special privileges are required.
- X `#' is used when SUPER USER privileges may be required.
- X
- X
- X STEP 1
- X
- X CONFIGURATION OF MAKEFILE
- X -------------------------
- X
- XCheck the 'Makefile' file and supply the proper values for the
- Xfollowing parameters:
- X
- XCC The command to invoke the C compiler
- X
- XCPP The command to invoke the C preprocessor with the result
- X written to the standard output stream.
- X
- XCFLAGS Flags to the C compiler (e.g. -O or -g)
- X
- X
- X STEP 2
- X
- X CREATE CONFIGURATION FILE config.h
- X ----------------------------------
- X
- XThe configuration file is distributed in the file config.h-dist. You
- Xmust COPY this to config.h before proceeding. Keep the original -dist
- Xfile to allow patches to be applied to it if necessary.
- X
- X $ cp config.h-dist config.h
- X
- X
- X STEP 3
- X
- X EDIT config.h TO REFLECT YOUR SYSTEM
- X ------------------------------------
- X
- XFor each required configuration parameter, the config.h file contains
- Xverbose comments explaining the meaning of each parameter in the file.
- XRead and follow these instructions carefully. If you do that, nn
- Xshould compile and run without problems.
- X
- XFurther information about the parameters can be found below in case
- Xyou are in doubt. Regarding the NNTP related definitions, consult the
- Xfile named NNTP.
- X
- XNotice that every time you edit config.h, the file update.h is
- Xmodified to make a new configuration level for the version in the
- Xsource directory. The current configuration is showed in the version
- Xstring as #number.
- X
- X
- X STEP 3.1: SPECIFY NETWORK AND NNTP CONFIGURATION
- X ------------------------------------------------
- X
- XIf you use nn on a single system with news on its local disks, you
- Xwill not have to worry the least about networking, and you simply
- Xleave NETWORK_DATABASE and NNTP undefined.
- X
- XOtherwise, consult the file NNTP for further instructions on sharing
- Xthe news file and/or the database via NFS and/or NNTP.
- X
- X
- X STEP 3.2: SELECT SYSTEM FILE
- X ----------------------------
- X
- XAmong the things you have to select are two system and machine
- Xdependent files (residing in the `conf' subdirectory). The following
- Xsystem files are delivered with nn:
- X
- X s-3b1g.h For 3b1 (unix-pc) with GCC.
- X s-aix221.h For AIX 2.2.1
- X s-aux1-1.h For A/UX 1.1
- X s-bsd4-2.h For 4.2 BSD and Ultrix systems
- X s-bsd4-3.h For 4.3 BSD systems
- X s-dnix5-2.h For dnix 5.2 on DIAB DS90.
- X s-dnix5-3.h For dnix 5.3 on DIAB DS90.
- X s-dynix3-0.h For Dynix 3.0 on Symmetry.
- X s-fortune.h For Fortune 32:16 [read comments in the file]
- X s-hpux.h For HPUX (series 300)
- X s-hpux2-1.h For HPUX 2.1 (series 800)
- X s-hpux3-0.h For HPUX 3.0 (series 800)
- X s-hpux6-5.h For HPUX 6.5 or newer (series 300)
- X s-pyramid.h For Pyramid (and Targon 35).
- X s-sgi4D.h For IRIX 3.1/3.2 [read comments in the file]
- X s-sunos3.h For SunOS 3
- X s-sunos4-0.h For SunOS 4.0
- X s-sys5.h For most system V based systems.
- X s-sys5-tcap.h For system V using termcap rather than terminfo.
- X s-texas1500.h For Texas Instruments System 1500.
- X s-tower32.h For NCR tower
- X s-umipsb.h For Mips running riscos 4.0 or greater
- X s-uport2-2.h For Microport UNIX V.2
- X s-usg3-1.h For most system V systems (obsolete)
- X s-xenix386.h For xenix386 [termcap version].
- X s-xenix386ds.h For Xenix386 2.3.2 w/development system.
- X
- XIf none of these can be used on your system, create your own based on
- Xthe file conf/s-template.h.
- X
- X
- X STEP 3.3: SELECT MACHINE FILE
- X -----------------------------
- X
- XThe following machine description files are delivered with nn:
- X
- X m-3b1g.h For 3b1 (unix-pc) with GCC [no networking].
- X m-att3b.h For AT&T 3b2 (with s-usg3-1.h)
- X m-convex.h For Convex.
- X m-dec3100.h For DECstation 3100 (with s-bsd4-2.h)
- X m-gould.h For Gould PN6000 (with s-bsd4-3.h)
- X m-hp9000.h For HP9000 series 320 and 800 (at least)
- X m-i80286.h For Intel 80286 processors [no network support]
- X m-i80386.h For Intel 80386 processors [no network support]
- X m-m680x0.h For Motorola 68000 family processors
- X m-m88000.h For Motorola 88000 risc processors
- X m-mips.h For MIPS processors
- X m-pyramid.h For Pyramid (and Targon 35).
- X m-rt6150.h For IBM 6150
- X m-sgi4D.h For Silicon Graphics 4D series.
- X m-sparc.h For SPARC processors
- X m-sun386i.h For 80386 based SUNs [have network support]
- X m-symmetry.h For Sequent Symmetry.
- X m-vax.h For VAX family
- X
- XIf you cannot use one of these machine files create your own based on
- Xthe file conf/m-template.h.
- X
- X
- X STEP 3.4: LOCALIZE NN
- X ---------------------
- X
- XYou will have to specify a number of files and directories which nn
- Xhas to know about to work properly. If you don't specify these, nn
- Xwill in most cases use it own alternatives which will correspond to
- Xcommon practices on most installations.
- X
- XThe following directories and files can be defined in config.h:
- X
- X
- XBIN_DIRECTORY (mandatory)
- X
- X The directory where you want the user programs to be
- X installed. The following programs will be installed in that
- X directory:
- X
- X nn The news reader program
- X nnacct Accounting, quota, and access management
- X nnadmin The administration program (link to nn)
- X nncheck Check for unread articles (link to nn)
- X nngoback Mark older articles as unread (link to nn)
- X nngrab Faster keyword search
- X nngrep Grep for news groups (link to nn)
- X nnpost Standalone posting program (link to nn).
- X nnstats Collection and expiration statistics
- X nntidy Cleans up the rc file (link to nn)
- X nnusage Show usage statistics
- X
- X
- XLIB_DIRECTORY
- X
- X The directory where nn's auxiliary programs and files will
- X be installed unless another directory is specified by one of
- X the following definitions.
- X
- X
- XMASTER_DIRECTORY (optional, default = LIB_DIRECTORY)
- X
- X The directory containing the nnmaster daemon programs. It
- X should not be shared in a networked environment!
- X
- X back_act
- X Program to make daily copies of the active file to
- X allow nngoback to work.
- X
- X nnmaster
- X The program building and maintaining nn's database.
- X
- X nnspew Program to build a tertiary subject database for
- X nngrab.
- X
- X MPID Exclusive lock file created by the currently running
- X nnmaster daemon process. Accessed by nnadmin to
- X get the daemon's process id.
- X
- X GATE Message file created by nnadmin and deleted by nnmaster.
- X
- X
- XCLIENT_DIRECTORY (optional, default = LIB_DIRECTORY)
- X
- X Contains the auxiliary programs and files required by the nn
- X program:
- X
- X aux The shell script used in connection with replies etc.
- X It knows about common editors like vi and gnu emacs to
- X have them position the cursor appropriately. To add
- X support for your own favourite editor, you should edit
- X the file aux.sh, not the compiled `aux' script!
- X
- X upgrade_rc
- X Script used by nn to convert release 6.3 rc files to
- X .newsrc format when first invoked after upgrade to 6.4.
- X
- X
- XHELP_DIRECTORY (optional, default = CLIENT_DIRECTORY/help)
- X
- X The directory where the help files and online manual are
- X stored. This directory is an obvious candidate for sharing in
- X a network.
- X
- X
- XCACHE_DIRECTORY (optional, default = each user's .nn directory)
- X
- X Only used with NNTP!! Directory to be used as a common storage
- X for temporary cache files when nn is used with NNTP. Using a
- X common directory for cache files allows you to clean these out
- X on reboot with a single "rm" command in the rc file:
- X (cd CLIENT_DIRECTORY; rm -f *)
- X
- X
- XTMP_DIRECTORY (optional, default = /usr/tmp)
- X
- X The directory to be used as temporary storage for files used
- X when editing responses etc.
- X
- X
- XNEWS_DIRECTORY (optional, default = /usr/spool/news)
- X
- X The directory containing the news spool directories and files.
- X It is not required when a remote NNTP server is used.
- X
- X
- XNEWS_LIB_DIRECTORY (optional, default = /usr/lib/news)
- X
- X The directory containing the news system's active file and
- X other related files.
- X
- X When a remote NNTP server is used, it is still needed as the
- X location of the (mini-)inews program if posting is allowed
- X (unless INEWS is explicitly defined to override the default
- X location).
- X
- X
- XLOG_FILE (optional, default = LIB_DIRECTORY/Log)
- X
- X The log file used by nnmaster and nn to store reports, error
- X messages, usage statistics, etc.
- X
- X
- X STEP 3.5: WHERE DO YOU WANT THE DATABASE?
- X -----------------------------------------
- X
- XThe following definitions in config.h are used to control where the
- Xdatabase maintained by nnmaster is stored. The database consists of a
- Xcouple of files containing global information for all existing groups,
- Xand a pair of files for each non-empty group. The database requires
- Xsome disk space to hold the necessary information. On average about
- X100 bytes per article in the system, or about 5% of the space
- Xallocated to the news articles.
- X
- XThe database is intended to be shared together with the news spool
- Xdirectory in a networked environment provided that NETWORK_DATABASE is
- Xdefined in config.h.
- X
- XIf DB_DIRECTORY is not defined, the global database files will be
- Xlocated in a directory named NEWS_DIRECTORY/.nn, and the per-group
- Xfiles will be located in each individual news group's directory (named
- X.nnd and .nnx). Using this strategy will normally require that
- Xnnmaster is owned "news" (OWNER in config.h).
- X
- XThe location of the database can be changed via the following
- Xdefinitions in config.h:
- X
- XDB_DIRECTORY (optional, default = see above)
- X The directory containing the global database information files.
- X If you share /usr/spool/news via NFS or RFS, you can set DB to
- X something like /usr/spool/news/.nn to share it automatically
- X with /usr/spool/news.
- X
- XDB_DATA_DIRECTORY (optional, default = DB_DIRECTORY/DATA)
- X When DB_DIRECTORY is defined, the per-group files will no
- X longer be stored in the group directories, but in a single
- X common directory specified by DB_DATA_DIRECTORY. The files in
- X this directory will be named either by group number or by
- X group name (if DB_LONG_NAMES is also defined).
- X
- X
- XThe files config.h and NNTP describes how to share the database
- Xbetween several machines (also when you don't use NNTP).
- X
- X
- X STEP 4
- X
- X COMPILE THE SOFTWARE
- X --------------------
- X
- XTo compile the software, you just have to run one of the following
- Xmake commands.
- X
- XIf you are making a complete package with both master and client, do
- X
- X $ make all
- X
- XIf you want to share a database which resides on another host (through
- XNFS/RFS/rdist), you don't need a master on the local system, so you
- Xcan do the following instead:
- X
- X $ make client
- X
- X
- X STEP 5
- X
- X INSTALLING THE SOFTWARE
- X -----------------------
- X
- XInstallation of the nn software is handled entirely via a script
- X"./inst" created during the compilation. The components of nn are
- Xsplit into five parts, which can be installed separately or in various
- Xcombinations depending on whether you run a stand-alone system or
- Xnetworked systems sharing the database and other parts of the nn
- Xpackage. The five components are:
- X
- X1) Master files and programs (machine dependent)
- X Install the MASTER_DIRECTORY programs.
- X
- X2) User files and programs (machince dependent, shareable)
- X Install the BIN_DIRECTORY programs.
- X
- X3) Help files and auxiliary programs (shareable)
- X Install the CLIENT_DIRECTORY and HELP_DIRECTORY files and programs.
- X
- X4) Documentation (shareable)
- X Install the MAN pages in the proper directories.
- X
- X5) Online manual (shareable with 3)
- X Format and install the online manual in HELP_DIRECTORY.
- X
- X
- XUnless you have defined yourself as the owner of the nn package and
- Xhave write permission on all the necessary directories, you will need
- Xto be super-user to install nn, so start with
- X
- X $ su
- X
- XNow run the installation script:
- X
- X # ./inst
- X
- XThe `inst' script will list a menu with the following choices:
- X
- X(1)-(5) Install individual parts of the package.
- X
- X(s) Install a complete server + client package (1-5).
- X
- X(c) Install a client which accesses all its support files and
- X the database via a network (2).
- X
- X(n) Install a client accessing only the database via a network (2-5).
- X
- X(m) Install only the nnmaster (1).
- X
- X(c) Install only the client programs (2).
- X
- X(u) Update already installed parts of the package. This will
- X check for the existence of the old programs, and only update
- X programs and files already installed. You will typically use
- X this after applying patches.
- X
- XYou can also run the `inst' script with the choices as arguments, e.g.
- X
- X ./inst m c
- X
- X
- XNOTICE: Since nnmaster runs setuid OWNER, all users can potentially
- X kill the running master, initialize the database etc. if they
- X have access to execute the master. So either restrict the
- X permissions to execute nnmaster or the access to the directory
- X containing it. The default installation puts modes -rwsr-x---
- X on nnmaster and leaves the directory "open" which may not be
- X adequate for you.
- X
- X
- X STEP 6
- X
- X INITIALIZE THE DATABASE
- X -----------------------
- X
- XIf you have installed the nnmaster on the current system, you now have
- Xto initialize the database:
- X
- X $ su -- also as superuser
- X # ./inst INIT
- X
- XIf something goes wrong in this step, e.g. problems with the active
- Xfile, you must redo the initialization after fixing the other
- Xproblems.
- X
- XWhen the INIT operation completes, a database with empty entries for
- Xall the currently existing groups will have been created. If you want
- Xsome special actions to be performed for specific groups as described
- Xin the nnmaster manual, you must now edit the GROUPS file created by
- Xnnmaster in the DB_DIRECTORY. If you modify the GROUPS file, you must
- Xrun the following command to register the changes to the GROUPS file.
- X nnmaster -G
- X
- XWhen you are ready, you must start nnmaster to enter all the existing
- Xarticles into the database. If you use the following command,
- Xnnmaster will fork and return immediately; its background child will
- Xcontinue to update the database whenever new articles arrive:
- XIt will ignore articles which are more than 45 days old (-O).
- X
- X $ MASTER_DIRECTORY/nnmaster -r -O45
- X
- XIt may take quite a while before all existing articles have been
- Xentered into the database. You can use nnadmin's (U)pdate and (S)tat
- Xcommands to trace the progress and the (L)og command to see if it has
- Xfinished (a C entry will occur). You will see that many groups will
- Xbe BLOCKED, but the number should decrease as nnmaster gets through
- Xmore and more groups.
- X
- XYou can also use the following command to do the initial collection of
- Xarticles from a terminal and get a nice trace of the action:
- X
- X nnmaster -D -O45
- X
- XOne or two numbers will be shown while a group is being collected.
- XThe first number is the number of the article currently being read.
- XThe (optional) second number will be the number of old (or bad)
- Xarticles which nnmaster has ignored in the group so far.
- X
- X
- XNOTICE: If the system file you have used does not specify how to
- X detatch a process from its controlling terminal, the nnmaster
- X may die when you log out.
- X
- XWhen nnmaster has finished the initial collection the articles, you
- Xcan nnadmin's (V)alidate command to verify that the database build by
- Xnnmaster is consistent (restart nnadmin before verifying).
- X
- X
- X STEP 7
- X
- X UPDATE SYSTEM FILES
- X -------------------
- X
- XYou will have to edit some of the scripts and files on your system to
- Xget the database and other support files updates automatically, also
- Xfollowing system shutdown, crashes, etc.
- X
- X
- X STEP 7.1: START NNMASTER WHEN SYSTEM IS BOOTED
- X ----------------------------------------------
- X
- XTo have the database updated at all times, the nnmaster should be
- Xstarted when the system is booted.
- X
- XThere will be a file named /etc/rc, a directory /etc/rc.d, or
- Xsomething similar on your system which contains commands that are
- Xexecuted when the system is booted. The following commands should be
- Xadded to the boot scripts:
- X
- X rm -f MASTER_DIRECTORY/MPID
- X MASTER_DIRECTORY/nnmaster -l -r -C
- X
- X
- XAlternatively, you can arrange for cron to run the master regularly.
- XIn this case, you should not use the -r and -C options. Instead, you
- Xshould let cron execute the command 'nnadmin Z' once a day to
- Xvalidate the database. For example:
- X
- X 0,10,20,30,40,50 * * * * MASTER/nnmaster -LM
- X 0 0 * * * BIN/nnadmin Z
- X
- X
- XWARNING: If you share the database via NFS or RFS, nnmaster should run
- X only on the system where the database actually resides!!
- X And preferably it should run on the host where the news spool
- X directory is located as well. This will improve speed as well
- X as reliability (NFS can suffer from time out problems).
- X
- X
- X STEP 7.2: SETUP EXPIRE ON THE DATABASE
- X --------------------------------------
- X
- XTo run expire on the database, you simply have to execute the
- Xfollowing command (with sufficient privileges):
- X
- X BIN_DIRECTORY/nnadmin =EYW
- X
- XYou should arrange for expire to be run on nn's database whenever you
- Xhave run expire on the news directories.
- X
- XSupposing you run the expire from your crontab, you may simply add the
- Xabove command to the crontab at an appropriate time when you are
- Xcertain that news' expire is completed.
- X
- XIf you run nnmaster from cron rather than in daemon mode, you can use
- Xthe following command to run expire on the database.
- X
- X nnmaster -F -k ""
- X
- XThis form allows you to run expire on selected groups rather than on
- Xall groups as initiated by the above nnadmin command. See the
- Xnnmaster manual for further details.
- X
- X
- X STEP 7.3: SAVE A COPY OF THE ACTIVE FILE ONCE A DAY
- X ---------------------------------------------------
- X
- XThe `nngoback' program requires that the program `back_act' is
- Xexecuted once (and only once) every day to maintain suitable copies of
- Xthe active files for the last 14 days. In a network environment, it
- Xshould execute on the same host as the nnmaster.
- X
- XSimply arrange for back_act to be invoked by cron once a day
- X(preferably just before the batch of news for `today' arrives). For
- Xexample, assuming the news is received just before midnight (syntax
- Xand location of crontab entry may vary):
- X
- XIn /usr/spool/cron/crontabs/news (System V):
- X 00 23 * * * MASTER_DIRECTORY/back_act
- Xor in /usr/lib/crontab (BSD):
- X 00 23 * * * su - news MASTER_DIRECTORY/back_act
- X
- X
- X STEP 7.4: PREPARE FOR NNSPEW TO BE RUN REGULARLY
- X -------------------------------------------------
- X
- XThe nngrab program will run faster if a dedicated subject database in
- Xaddition to the normal database is available. To maintain this
- Xadditional database, the program nnspew must be executed regularly,
- Xe.g. from cron. Every 3-6 hours should be sufficient to keep the
- Xdatabase reasonably up-to-date, e.g.
- X
- XIn /usr/spool/cron/crontabs/news (System V):
- X 2 6,12,18 * * * MASTER_DIRECTORY/nnspew
- Xor in /usr/lib/crontab (BSD):
- X 2 6,12,18 * * * su - news MASTER_DIRECTORY/nnspew
- X
- X
- X STEP 8
- X
- X INSTALL AND EDIT GLOBAL FILES
- X -----------------------------
- X
- XDepending on your needs, you should create the following files on each
- Xhost running nn (you may also just share the files if you like):
- X
- XCLIENT_DIRECTORY/init
- X The global init file for all users on the system. Users will
- X be able to override the definitions in this file, but you can
- X probably make some sensible decisions which will prevent
- X novice users from getting into trouble, for example set the
- X default distribution to "local" etc.
- X
- X You can also specify a global presentation sequence here.
- X
- X You may use init.sample as a starting point, but don't use it
- X without careful examination. Especially, the sequence part
- X is mainly an illustration of the possibilities. If you are in
- X doubt, just delete the sequence part of the file (groups will
- X then be presented in pure alphabetical order).
- X
- XCLIENT_DIRECTORY/routes
- X You DO NOT NEED this file if you already run a domain based
- X mailer, i.e. when HAVE_ROUTING is defined in config.h.
- X
- X Otherwise, you can use it as a configuration file for the
- X domain address remapping done by nn in reply addresses and the
- X nnmail program. You may use routes.sample as a starting point
- X (it briefly describes how to build a routes file).
- X
- X Please notice that neither the routes functionality, nor
- X nnmail is a supported part of nn - if you really want to
- X run a domain-based mailer, get smail 2.5 or later. And if you
- X ask me how to use it I will answer: "Get SMAIL instead".
- X
- X
- XNNTP_SERVER
- X Must contain the host name of the NNTP-server when NNTP is
- X used. If you already run NNTP with your other news readers,
- X this file does not need to be modified.
- X
- X
- X STEP 9
- X
- X TEST THE BASIC FUNCTIONS
- X ------------------------
- X
- XIf any of the following tests fails or you see other peculiar
- Xbehaviour, you should consult the PROBLEMS file. You may not be the
- Xonly one to have seen the problems, and there might even be a solution.
- X
- XFirst you should check that nnmaster does collect the articles it is
- Xsupposed to. Here, nnadmin is a great help, since you can peek around
- Xin all the database files and see what nnmaster is doing. nnadmin
- Xtakes a snap-shot of the database when it starts up, but you can take
- Xa new snap-shot anytime using the (U)pdate command.
- X
- XAlso look at the (L)og to see that there were no problems while
- Xcollecting the articles.
- X
- XThere are a few things you should check to ensure the proper
- Xfunctioning of nn.
- X
- X1) Backup your current .newsrc file if you have one. (Don't save it
- X in .newsrc.bak or .newsrc.orig since nn may use these names).
- X
- X2) Run `nn'. If you have upgraded from release 6.3, nn will convert
- X your release 6.3 .nn/rc file into a .newsrc file.
- X
- X3) Does nn find any news? If not, does nn -x find anything?
- X
- X4) Can you send mail to yourself? Try the sequence:
- X m (return) (return) testing (return)
- X edit the letter
- X s (return)
- X
- X If not, you should check the REC_MAIL program.
- X
- X5) Can you post an article to the local test group? Try:
- X :post (return)
- X test (return)
- X local (return)
- X edit the article
- X s (return)
- X
- X If not, you should check the INEWS program.
- X
- X
- X -------------------------------------------
- X IF EVERYTHING WORKS
- X YOU HAVE COMPLETED THE INSTALLATION
- X -------------------------------------------
- X
- X
- X UPDATING THE SOFTWARE
- X ---------------------
- X
- XPatches to this software will be distributes as context diff's which
- Xcan be applied using Larry Wall's `patch' program.
- X
- XAfter applying the patches, you will need to redo the compilation and
- Xinstallation steps:
- X
- X $ patch < PATCH_FILE (or use nn's :patch command)
- X $ make all
- X $ su
- X # ./inst u
- X
- XTo be able to install a new nnmaster, the currently running master (if
- Xany) will be stopped automatically, and it has to be started manually
- Xwhen the installation is complete (unless it is setup to be run by cron).
- X
- XNotice that unless it is explicitly required in the patch, there is no
- Xneed to reinitialize the database after applying the patch.
- END_OF_FILE
- if test 23184 -ne `wc -c <'doc/INSTALLATION'`; then
- echo shar: \"'doc/INSTALLATION'\" unpacked with wrong size!
- fi
- # end of 'doc/INSTALLATION'
- fi
- if test -f 'man/nnacct.1m' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'man/nnacct.1m'\"
- else
- echo shar: Extracting \"'man/nnacct.1m'\" \(3905 characters\)
- sed "s/^X//" >'man/nnacct.1m' <<'END_OF_FILE'
- X.TH NNACCT 1m "Release 6.4"
- X.UC 4
- X.SH NAME
- Xnnacct \- news accounting and access authorization (nn)
- X.SH SYNOPSIS
- X\fBnnacct\fP \-\fBr\fP [ \-\fBf\fP file ] [ \-\fBa\fP ] [ user ]...
- X.br
- X\fBnnacct\fP \-\fBp\fP\fIpolicy\fP \-\fBq\fP\fIquota\fP user...
- X.SH DESCRIPTION
- XThe \fInnacct\fP command provides an optional accounting and access
- Xauthorization for news reading via the \fInn\fP news reader.
- X.LP
- XThe first form (\-\fBr\fP) is used to print accounting reports.
- XIf a \fIfile\fP is specified data from a saved accounting file;
- Xotherwise the data is read from the current accounting file.
- X.LP
- XIf \-\fBa\fP is specified, the report will contain accounting data for
- X\fIall\fP users. Otherwise, if one or more \fIusers\fP are specified,
- Xthe data for these users will be printed. If neiter is specified,
- Xonly the accounting data for the current user is printed.
- X Only the super-user can generate reports for other users than the
- Xcaller.
- X.LP
- XThe second form (\-\fBp\fP and/or \-\fBq\fP) assigns the specified
- Xaccess \fIpolicy\fP and/or \fIquota\fP to the specified users. If a
- Xgiven user is not already known in the accounting file, a new entry
- Xwith the specified policy and quota is created (default values are
- Xused if both are not specified).
- X.LP
- XThe following policies are currently implemented:
- X.TP
- X\fB0\fP
- XNo access. The user is not allowed to read news at all.
- X.TP
- X\fB1\fP
- XPrivileged user. The user can read news at all times and no
- Xaccounting information is saved. This is obviously the policy for
- Xsystem administrators :-)
- X.TP
- X\fB2\fP
- XFull time access. The user can access news at all times.
- X.TP
- X\fB3\fP
- XOff-hours access. The user can only access news at off hours, i.e. in
- Xthe morning, in the evening, on week-ends, and on holidays (not
- Xcomplete \- check the source :-)
- X.LP
- XThe \fIquota\fP specifies a number of \fIhours\fP which the user is
- Xallowed to read news. When this quota is used up, access will be
- Xblocked. A quota of zero gives unlimited access.
- X.LP
- XNew users will get the \fIdefault policy\fP and \fIquota\fP defined in
- Xaccount.c. If this allows new users to read news at only specific
- Xtimes, this form can be used to permit individual users to read news
- Xat all times, or it can be used to prevent them from reading news at
- Xall. If the default policy does not allow new users to read news,
- Xthis form must be used to authorize them to read news.
- X.SH HOW IT WORKS
- XIf authorization is enabled, the \fInn\fP news reader will call
- X\fInnacct\fP on start-up to check whether the policy and quota defined
- Xfor the current user allows him to read news at this time (or at all).
- X.LP
- XIf accounting is enabled, the \fInn\fP news reader will call
- X\fInnacct\fP on exit to register the time spent on news reading.
- XIf account logging is also defined (see account.c), an line is also
- Xadded to the accounting log file.
- X.LP
- XWhen accounting is defined, the user can use the \fB:cost\fP command
- Xto get the current accounting data, and if the variable
- X\fBreport-cost\fP is set, \fInn\fP will print accounting information
- Xon exit.
- X.SH CONTIGURATION AND NEW POLICIES
- XThe use of \fInnacct\fP is enabled via the ACCOUNTING and
- XAUTHORIZE symbols in \fInn\fP's configuration file. Further
- Xconfiguration of cost calculations, logging, default policy, default
- Xquotas, etc. is done directly in the source file \fIaccount.c\fP. New
- Xaccess policies can also be defined in this file. This allows you to
- Xchange the policies or prices without having to recompile the whole
- Xpackage since only \fInnacct\fP is modified.
- X.SH FILES
- X.DT
- X.ta \w'$db/acctlog'u+3m
- X.\"ta 0 16
- X$db/acct accounting data (accumulated per user)
- X.br
- X$db/acctlog accounting log (grows indefinitely)
- X.DT
- X.SH SEE ALSO
- Xnn(1), nnusage(1)
- X.SH BUGS
- XThere should be some tools to mess around with the accounting files,
- Xe.g. to make summaries, clear usage counters, etc.
- X.SH AUTHOR
- XKim F. Storm, Texas Instruments A/S, Denmark
- X.br
- XE-mail: storm@texas.dk
- END_OF_FILE
- if test 3905 -ne `wc -c <'man/nnacct.1m'`; then
- echo shar: \"'man/nnacct.1m'\" unpacked with wrong size!
- fi
- # end of 'man/nnacct.1m'
- fi
- if test -f 'more.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'more.c'\"
- else
- echo shar: Extracting \"'more.c'\" \(24124 characters\)
- sed "s/^X//" >'more.c' <<'END_OF_FILE'
- X/*
- X * (c) Copyright 1990, Kim Fabricius Storm. All rights reserved.
- X *
- X * Article browser.
- X */
- X
- X#include "config.h"
- X#include "news.h"
- X#include "term.h"
- X#include "menu.h"
- X#include "keymap.h"
- X#include "regexp.h"
- X
- Xexport int monitor_mode = 0;
- Xexport int compress_mode = 0;
- Xexport int show_article_date = 1;
- Xexport int first_page_lines = 0;
- Xexport int overlap = 2;
- Xexport int mark_overlap = 0;
- Xexport char *header_lines = NULL;
- Xexport int min_pv_window = 7;
- Xexport int wrap_headers = 6;
- Xexport int data_bits = 7;
- Xexport int scroll_clear_page = 1;
- Xexport int expired_msg_delay = 1;
- X
- Ximport int preview_window;
- Ximport int novice;
- Ximport int slow_mode;
- Ximport int auto_preview_mode;
- Ximport int flush_typeahead;
- Ximport int case_fold_search;
- X
- Ximport char delayed_msg[];
- X
- Xextern char *init_save();
- X
- Xstatic int rot13_must_init = 1;
- Xstatic char rot13_table[128];
- Xexport int rot13_active = 0;
- X#define ROT13_DECODE(c) ((c & 0x80) ? c : rot13_table[c])
- X
- Xstatic int compress_space;
- X
- Xstatic regexp *regular_expr = NULL;
- X
- X#define LINEMAX 100 /* most articles are less than 100 lines */
- X
- Xstatic struct header_def {
- X char field;
- X char *text;
- X char **news;
- X char **digest;
- X} header_defs[] = {
- X 'A', "Approved", &news.ng_appr, 0,
- X 'B', "Distribution",&news.ng_dist, 0,
- X 'D', "Date", &news.ng_date, &digest.dg_date,
- X 'F', "From", &news.ng_from, &digest.dg_from,
- X 'I', "Message-Id", &news.ng_ident, 0,
- X 'K', "Keywords", &news.ng_keyw, 0,
- X 'L', "Lines", &news.ng_xlines, 0,
- X 'N', "Newsgroups", &news.ng_groups, 0,
- X 'O', "Organization",&news.ng_org, 0,
- X 'P', "Path", &news.ng_path, 0,
- X 'R', "Reply-To", &news.ng_reply, 0,
- X 'S', "Subject", &news.ng_subj, &digest.dg_subj,
- X 'W', "Followup-To", &news.ng_follow, 0,
- X 'X', "References", &news.ng_ref, 0,
- X 'Y', "Summary", &news.ng_summ, 0,
- X 'd', "Date-Received", &news.ng_rdate, 0,
- X 'n', "Newsgroups", &news.ng_groups, 0,
- X 'x', "Back-Ref", &news.ng_bref, 0,
- X 0
- X};
- X
- Xstatic char *a_st_flags(flag)
- Xflag_type flag;
- X{
- X static char buf[40];
- X register char *cp;
- X static flag_type prevflag = 0;
- X
- X flag &= A_ST_FILED | A_ST_REPLY | A_ST_FOLLOW;
- X if (flag == 0) {
- X prevflag = 0;
- X return "";
- X }
- X
- X if (flag == prevflag) return buf;
- X prevflag = flag;
- X
- X cp = buf;
- X *cp++ = '(';
- X if (flag & A_ST_FILED) {
- X *cp++ = 'F';
- X *cp++ = 'i';
- X *cp++ = 'l';
- X *cp++ = 'e';
- X *cp++ = 'd';
- X }
- X
- X if (flag & A_ST_REPLY) {
- X if (cp[-1] != '(') *cp++ = SP;
- X *cp++ = 'R';
- X *cp++ = 'e';
- X }
- X
- X if (flag & A_ST_FOLLOW) {
- X if (cp[-1] != '(') *cp++ = SP;
- X *cp++ = 'F';
- X *cp++ = 'o';
- X *cp++ = 'l';
- X }
- X
- X strcpy(cp, ")------");
- X return buf;
- X}
- X
- Xmore(ah, mode, screen_offset)
- Xarticle_header *ah;
- Xint mode, screen_offset;
- X{
- X register int c, col, lno;
- X register FILE *art;
- X int more_cmd, eof, skip_spaces, has_space, window_lines;
- X int form_feed, last_ff_line, ignore_nl;
- X off_t firstl, lastl;
- X off_t lineposbuf[LINEMAX];
- X off_t *linepos = lineposbuf;
- X int linemax = LINEMAX;
- X char linebuf[200], *lp, skip_char;
- X int skip_wrap;
- X news_header_buffer ngheader, dgheader;
- X struct news_header news_save;
- X struct digest_header digest_save;
- X int linenum, maxline, topline, print_lines, lno1;
- X int underline_line, fake_underline;
- X int match_lines, match_redraw, match_topline, match_botline;
- X int goto_line, prev_goto, stop_line, extra_lines;
- X flag_type in_digest = ah->flag & A_DIGEST;
- X article_header digestah;
- X char *fname, *hdrline;
- X extern STANDOUT;
- X char pr_fmt[60], send_date[40];
- X int match_expr;
- X char *match_start, *match_end;
- X int open_modes, hdr_mode, o_mode;
- X struct header_def *hdef;
- X extern int alt_cmd_key, in_menu_mode, any_message;
- X#ifdef RESIZING
- X int entry_col = Columns;
- X#endif
- X extern char *pct();
- X
- X#define more_return(cmd) \
- X { more_cmd = cmd; goto more_exit; }
- X
- X if (ah->a_group != NULL) init_group(ah->a_group);
- X
- X open_modes = SKIP_HEADER;
- X if (show_article_date || header_lines) {
- X open_modes |= FILL_NEWS_HEADER;
- X if (header_lines == NULL)
- X open_modes |= GET_DATE_ONLY;
- X else
- X open_modes |= GET_ALL_FIELDS;
- X if (in_digest) open_modes |= FILL_DIGEST_HEADER;
- X }
- X
- X art = open_news_article(ah, open_modes, ngheader, dgheader);
- X
- X if (art == NULL) {
- X if (expired_msg_delay >= 0) {
- X msg("Expired: \"%s: %-.50s\"", ah->sender, ah->subject);
- X if ((mode & MM_PREVIEW) == 0 && expired_msg_delay > 0)
- X user_delay(expired_msg_delay);
- X }
- X return MC_NEXT;
- X }
- X
- X o_mode = in_menu_mode;
- X in_menu_mode = 0;
- X
- X if (screen_offset)
- X if (preview_window < 1 && Lines - screen_offset < min_pv_window)
- X screen_offset = 0;
- X else {
- X so_printxy(0, screen_offset++, "%s: %s ", ah->sender, ah->subject);
- X if (!STANDOUT) screen_offset++;
- X clrline();
- X }
- X
- X if (show_article_date) {
- X if (in_digest && digest.dg_date)
- X strncpy(send_date, digest.dg_date, 40);
- X else
- X if (news.ng_date) {
- X strncpy(send_date, news.ng_date, 40);
- X } else
- X send_date[0] = NUL;
- X send_date[39] = NUL;
- X if (lp = strrchr(send_date, ':')) *lp = NUL;
- X }
- X
- X linepos[0] = ah->hpos;
- X linepos[1] = firstl = ah->fpos;
- X maxline = 1;
- X topline = 1;
- X hdrline = screen_offset == 0 ? header_lines : "";
- X
- X lastl = (ah->lpos - firstl + 99)/100;
- X if (lastl == 0) lastl = 1; /* impossible ? */
- X
- X rot13_active = 0;
- X compress_space = compress_mode;
- X last_ff_line = goto_line = -1, prev_goto = 1;
- X skip_char = NUL; skip_wrap = 0;
- X match_lines = match_redraw = match_expr = 0;
- X underline_line = -1;
- X fake_underline = 0;
- X
- X stop_line = first_page_lines ? first_page_lines : -1;
- X
- X sprintf(pr_fmt,
- X "\1\2-- %s%s %s-----%%s%s-----%%s\1",
- X (mode & MM_PREVIEW) ? "PREVIEW " : "",
- X (mode & MM_DIGEST) ? "FULL DIGEST" :
- X (mode & MM_LAST_SELECTED) ? "LAST ARTICLE" : "ARTICLE",
- X novice ? "-- help:? " : "",
- X (ah->flag & A_NEXT_SAME) ? " (+next)" : "");
- X
- X if (screen_offset) goto safe_redraw;
- X
- X redraw: /* redraw that will destroy whole screen */
- X screen_offset = 0;
- X
- X safe_redraw: /* redraw of "more window" only */
- X linenum = topline;
- X
- X next_page:
- X no_raw();
- X
- X s_keyboard = 0;
- X
- X if (stop_line) {
- X lno = screen_offset;
- X if (scroll_clear_page || linenum <= 1) {
- X if (lno) {
- X gotoxy(0, lno);
- X clrpage(lno);
- X } else
- X clrdisp();
- X }
- X
- X if (linenum == 1)
- X hdrline = screen_offset == 0 ? header_lines : "";
- X
- X print_header:
- X if (hdrline == NULL || *hdrline == '*') {
- X if (hdrline && *++hdrline == NUL) hdrline = NULL;
- X
- X if (linenum <= 1) {
- X if (linenum == 0 || (mode & MM_DIGEST)) {
- X if (screen_offset) {
- X lno--;
- X if (!STANDOUT) lno--;
- X gotoxy(0, lno);
- X }
- X
- X so_printxy(0, lno,
- X "Newsgroup: %s, article: %ld%s",
- X current_group->group_name,
- X (long)(ah->a_number),
- X ((mode & MM_DIGEST) || in_digest)
- X ? " *DIGEST*" : "");
- X/* fseek(art, linepos[0], 0); */
- X
- X lno++;
- X if (!STANDOUT) lno++;
- X } else {
- X if (screen_offset == 0 && linenum == 1) {
- X if (show_article_date) so_printxy(-1, 0, send_date);
- X
- X /* so_printxy will cut subject */
- X so_printxy(0, lno, "%s: %s ", ah->sender, ah->subject);
- X lno++;
- X if (!STANDOUT) lno++;
- X }
- X }
- X }
- X }
- X
- X if (hdrline && screen_offset == 0) {
- X
- X hdr_mode = 0;
- X while (*hdrline) {
- X
- X if (*hdrline == '*') goto print_header;
- X
- X if (*hdrline == '=') {
- X hdr_mode = 1;
- X hdrline++;
- X continue;
- X }
- X if (*hdrline == '_') {
- X hdr_mode = 2;
- X hdrline++;
- X continue;
- X }
- X for (hdef = header_defs; hdef->field; hdef++) {
- X if (hdef->field != *hdrline) continue;
- X if (in_digest) {
- X if (hdef->digest == NULL) break;
- X if ((lp = *(hdef->digest)) == NULL)
- X break;
- X } else
- X if ((lp = *(hdef->news)) == NULL)
- X break;
- X if (*hdrline == 'n')
- X if ((current_group->group_flag & G_MERGED) == 0 &&
- X strchr(lp, ',') == NULL) break;
- X
- X gotoxy(0, lno++);
- X printf("%s: ", hdef->text);
- X c = col = strlen(hdef->text) + 2;
- X split_header_line:
- X switch (hdr_mode) {
- X case 0:
- X break;
- X case 1:
- X highlight(1);
- X break;
- X case 2:
- X underline(1);
- X break;
- X }
- X while (*lp && c < Columns) {
- X if (isspace(*lp)) {
- X while (lp[1] && isspace(lp[1])) lp++;
- X if (wrap_headers > 0 &&
- X (c + wrap_headers) >= Columns &&
- X strlen(lp) >= wrap_headers) {
- X lp++;
- X break;
- X }
- X *lp = SP;
- X }
- X putchar(*lp++);
- X c++;
- X }
- X switch (hdr_mode) {
- X case 0:
- X break;
- X case 1:
- X highlight(0);
- X break;
- X case 2:
- X underline(0);
- X break;
- X }
- X if (*lp && wrap_headers >= 0) {
- X gotoxy(col, lno++);
- X c = col;
- X goto split_header_line;
- X }
- X break;
- X }
- X hdr_mode = 0;
- X hdrline++;
- X }
- X
- X hdrline = NULL;
- X putchar(NL);
- X lno++;
- X }
- X
- X lno1 = lno;
- X topline = linenum;
- X
- X window_lines = Lines - lno - 2;
- X print_lines = window_lines;
- X
- X ignore_nl = 1; /* ignore blank lines at top op screen */
- X } else {
- X putchar(CR);
- X clrline();
- X print_lines = extra_lines; /* LINT complaints here -- ignore */
- X }
- X
- X if (stop_line > 0) {
- X if (print_lines > stop_line) {
- X extra_lines = print_lines - stop_line;
- X print_lines = stop_line;
- X underline_line = -1;
- X }
- X stop_line = 0;
- X } else
- X stop_line = -1;
- X
- X next_line:
- X
- X if (linenum == linemax) {
- X linemax += 500;
- X if (linepos == lineposbuf) {
- X linepos = newobj(off_t, linemax);
- X for (linenum = 0; linenum < LINEMAX; linenum++)
- X linepos[linenum] = lineposbuf[linenum];
- X } else
- X linepos = resizeobj(linepos, off_t, linemax);
- X }
- X
- X if (goto_line == linenum) {
- X goto_line = -1;
- X goto next_page;
- X }
- X
- X eof = 0;
- X
- X if (linenum > maxline)
- X linepos[++maxline] = ftell(art);
- X else
- X if (linenum > 0)
- X fseek(art, linepos[linenum], 0);
- X
- X
- X if (linepos[linenum] >= ah->lpos) {
- X if (match_expr) {
- X match_expr = 0;
- X topline = match_topline; /* LINT complaints here -- ignore */
- X linenum = match_botline; /* LINT complaints here -- ignore */
- X fseek(art, linepos[linenum], 0);
- X msg("Not found");
- X goto Prompt;
- X }
- X eof++;
- X if (goto_line > 0) {
- X goto_line = -1;
- X linenum -= window_lines/2;
- X goto next_page;
- X }
- X goto Prompt;
- X }
- X
- X if (linenum == 0) {
- X if (ftell(art) >= linepos[1]) {
- X linenum = 2; /* current line is 1st line ! */
- X lno1 = lno;
- X }
- X } else
- X linenum++;
- X
- X lp = linebuf;
- X col = 0;
- X form_feed = 0;
- X
- X next_char:
- X
- X c = getc(art);
- X if (c == EOF) {
- X eof++;
- X if (lp == linebuf) goto Prompt;
- X goto end_line;
- X }
- X
- X if (c & 0200) {
- X if (monitor_mode || data_bits != 8) {
- X col += 4;
- X if (col > Columns) { /* then there is no room for M-^X */
- X ungetc(c, art);
- X goto long_line;
- X }
- X c &= 0177;
- X *lp++ = 'M';
- X *lp++ = '-';
- X if (c < SP) {
- X *lp++ = '^';
- X c += '@';
- X } else
- X col--;
- X }
- X } else
- X if (c < SP) {
- X if (monitor_mode) {
- X if (c == NL) {
- X *lp++ = '$';
- X goto end_line;
- X }
- X if (col + 2 > Columns) {
- X *lp++ = '\\';
- X ungetc(c, art);
- X goto end_line;
- X }
- X *lp++ = '^';
- X c += '@';
- X col++;
- X } else
- X switch (c) {
- X
- X case '\f':
- X last_ff_line = linenum;
- X if (lp == linebuf) {
- X if (goto_line > 0 || skip_char || match_expr || lno == lno1)
- X goto next_line;
- X form_feed = 1;
- X goto Prompt;
- X }
- X form_feed = 1;
- X goto end_line;
- X
- X case CR:
- X if (lp == linebuf || ignore_nl) goto next_char;
- X ignore_nl = 1;
- X goto end_line;
- X
- X case NL:
- X if (ignore_nl) {
- X ignore_nl = 0;
- X if (lp == linebuf) {
- X if (lno == lno1) {
- X ignore_nl = 1;
- X goto next_line;
- X }
- X goto next_char;
- X }
- X }
- X goto end_line;
- X
- X case BS:
- X if (col) {
- X lp--;
- X col--;
- X }
- X goto next_char;
- X
- X case TAB:
- X if (col + 8 - (col & 07) >= Columns)
- X goto long_line;
- X
- X do {
- X *lp++ = SP;
- X col++;
- X } while (col & 07);
- X goto next_char;
- X
- X default:
- X if (col + 2 > Columns) {
- X ungetc(c, art);
- X goto long_line;
- X }
- X *lp++ = '^';
- X c += '@';
- X col++;
- X break;
- X }
- X }
- X
- X *lp++ = c;
- X col++;
- X ignore_nl = 0;
- X
- X if (col < Columns) goto next_char;
- X
- Xlong_line:
- X ignore_nl = 1;
- X
- X end_line:
- X /* if we are seaching for a specific line, repeat until it is found */
- X if (skip_wrap) {
- X skip_wrap = ignore_nl;
- X goto next_line;
- X }
- X if (goto_line >= linenum) goto next_line;
- X if (skip_char) {
- X if (lp == linebuf || linebuf[0] == skip_char) {
- X skip_wrap = ignore_nl;
- X goto next_line;
- X }
- X skip_char = NUL;
- X if (overlap > 0) {
- X underline_line = linenum;
- X linenum -= overlap;
- X goto next_page;
- X }
- X }
- X
- X *lp++ = NUL;
- X
- X if (match_expr) {
- X if (!regexec_cf(regular_expr, linebuf))
- X goto next_line;
- X match_expr = 0;
- X match_lines = 1;
- X if (linenum > match_botline) {
- X match_redraw = 0;
- X if (last_ff_line > linenum) last_ff_line = -1;
- X linenum -= 5;
- X if (linenum < last_ff_line) linenum = last_ff_line;
- X goto next_page;
- X }
- X match_redraw = (stop_line < 0);
- X stop_line = -1;
- X lno = lno1 + linenum - topline - 1;
- X print_lines = window_lines - lno + lno1;
- X }
- X
- X /* now print the line */
- X
- X if (match_lines && underline_line != linenum &&
- X regexec_cf(regular_expr, linebuf)) {
- X match_start = regular_expr->startp[0];
- X match_end = regular_expr->endp[0];
- X } else {
- X if (match_redraw) goto no_print;
- X match_start = NULL;
- X }
- X
- X gotoxy(0, lno);
- X if (!scroll_clear_page) clrline();
- X
- X if (mark_overlap && underline_line == linenum)
- X if (!underline(1))
- X fake_underline = 1;
- X skip_spaces = has_space = 0;
- X
- X for (lp = linebuf; c = *lp; lp++) {
- X
- X if (match_start) {
- X if (lp == match_start) highlight(1);
- X if (lp == match_end) {
- X highlight(0);
- X match_start = NULL;
- X if (match_redraw) goto no_print;
- X }
- X }
- X
- X if (c == SP) {
- X if (skip_spaces) {
- X if (has_space) continue;
- X has_space++;
- X }
- X if (fake_underline) c = '_';
- X } else {
- X if (compress_space && c != ' ') {
- X skip_spaces = 1;
- X has_space = 0;
- X }
- X if (rot13_active && linenum > 0)
- X c = ROT13_DECODE(c);
- X }
- X
- X putchar(c);
- X }
- X
- X if (match_start) highlight(0);
- X
- X if (mark_overlap && underline_line == linenum) {
- X while (lp - linebuf < 10) {
- X putchar(fake_underline ? '_' : ' ');
- X lp++;
- X }
- X underline(0);
- X underline_line = -1;
- X fake_underline = 0;
- X }
- X
- Xno_print:
- X
- X ++lno;
- X if (--print_lines > 0 && s_keyboard == 0 && form_feed == 0) goto next_line;
- X
- X if (!eof && linenum >= maxline) {
- X if (ignore_nl) {
- X c = getc(art);
- X if (c == EOF)
- X eof++;
- X else if (c != NL)
- X ungetc(c, art);
- X else
- X ignore_nl = 0;
- X }
- X
- X if (!eof && ftell(art) >= ah->lpos) eof++;
- X }
- X
- X match_redraw = 0;
- X
- X Prompt:
- X
- X if (eof && lno == screen_offset) more_return(MC_NEXT);
- X
- X raw();
- X
- X prompt_line = lno;
- X
- X if (!scroll_clear_page)
- X clrpage(prompt_line);
- X
- X dflt_prompt:
- X
- X prompt(pr_fmt,
- X pct((long)(ah->fpos), (long)(ah->lpos),
- X (long)(linepos[topline]), (long)ftell(art)),
- X a_st_flags(ah->flag));
- X
- X if (delayed_msg[0] != NUL) {
- X msg(delayed_msg);
- X delayed_msg[0] = NUL;
- X }
- X
- X same_prompt:
- X
- X if (flush_typeahead) flush_input();
- X
- X if ((c = get_c()) & GETC_COMMAND)
- X c &= ~GETC_COMMAND;
- X else
- X c = more_key_map[c];
- X
- X if (s_hangup) c = K_QUIT;
- X
- X if (any_message) clrmsg(0);
- X
- X if (c & K_MACRO) {
- X m_invoke(c & ~K_MACRO);
- X goto same_prompt;
- X }
- X
- X alt_key:
- X
- X switch (c) {
- X case K_UNBOUND:
- X ding();
- X case K_INVALID:
- X goto same_prompt;
- X
- X case K_REDRAW:
- X#ifdef RESIZING
- X if (Columns != entry_col) {
- X entry_col = Columns;
- X maxline = topline = 1;
- X }
- X#endif
- X goto redraw;
- X
- X case K_NEXT_PAGE:
- X if (eof) {
- X ding();
- X goto same_prompt;
- X }
- X /* FALL THRU */
- X
- X case K_CONTINUE:
- X if (eof) break;
- X if (screen_offset == 0 && form_feed == 0 && stop_line) {
- X if (linenum > overlap) {
- X underline_line = linenum;
- X linenum -= overlap;
- X }
- X }
- X goto next_page;
- X
- X case K_LAST_MESSAGE:
- X msg((char *)NULL);
- X goto dflt_prompt;
- X
- X case K_HELP:
- X display_help("more");
- X goto redraw;
- X
- X case K_SHELL:
- X putchar(CR);
- X if (shell_escape()) goto redraw;
- X goto dflt_prompt;
- X
- X case K_EXTENDED_CMD:
- X news_save = news;
- X digest_save = digest;
- X more_cmd = alt_command();
- X news = news_save;
- X digest = digest_save;
- X
- X switch (more_cmd) {
- X
- X case AC_UNCHANGED:
- X goto same_prompt;
- X
- X case AC_QUIT:
- X more_return( MC_QUIT );
- X
- X case AC_PROMPT:
- X goto dflt_prompt;
- X
- X case AC_REENTER_GROUP:
- X more_return( MC_REENTER_GROUP );
- X
- X case AC_REORDER:
- X more_return( MC_MENU );
- X
- X case AC_REDRAW:
- X goto redraw;
- X
- X case AC_KEYCMD:
- X c = alt_cmd_key;
- X goto alt_key;
- X }
- X
- X case K_QUIT:
- X ah->attr = A_LEAVE_NEXT;
- X more_return( MC_QUIT );
- X
- X case K_SAVE_NO_HEADER:
- X case K_SAVE_SHORT_HEADER:
- X case K_SAVE_FULL_HEADER:
- X case K_PRINT:
- X case K_UNSHAR:
- X case K_PATCH:
- X case K_UUDECODE:
- X news_save = news;
- X digest_save = digest;
- X
- X putchar(CR);
- X if (init_save(c, (char **)NULL) != NULL) {
- X if (c == K_UNSHAR)
- X prompt_line = Lines - 2;
- X
- X save(ah);
- X end_save();
- X }
- X news = news_save;
- X digest = digest_save;
- X if (!slow_mode && (c == K_UNSHAR || c == K_PATCH)) {
- X printf("\r\n\n");
- X any_key(0);
- X goto redraw;
- X }
- X goto Prompt;
- X
- X case K_FOLLOW_UP:
- X#ifdef NNTP_POST
- X if (use_nntp && nntp_no_post()) goto Prompt;
- X#endif
- X case K_REPLY:
- X case K_MAIL_OR_FORWARD:
- X news_save = news;
- X digest_save = digest;
- X more_cmd = answer(ah, c, -1);
- X news = news_save;
- X digest = digest_save;
- X if (more_cmd)
- X if (slow_mode) clrdisp(); else goto redraw;
- X goto Prompt;
- X
- X case K_POST:
- X if (post_menu())
- X if (slow_mode) clrdisp(); else goto redraw;
- X goto Prompt;
- X
- X case K_CANCEL:
- X if (current_group->group_flag & G_FOLDER) {
- X prompt("%s this folder entry",
- X (ah->attr == A_CANCEL) ? "UNcancel" : "Cancel");
- X if (yes(0)) fcancel(ah);
- X goto Prompt;
- X }
- X
- X if (cancel(ah) > 0) goto Prompt;
- X more_return(MC_NEXT);
- X
- X case K_UNSUBSCRIBE:
- X if (!unsubscribe(current_group)) goto Prompt;
- X if ((current_group->group_flag & G_UNSUBSCRIBED) == 0) goto Prompt;
- X more_return(MC_NEXTGROUP);
- X
- X case K_GROUP_OVERVIEW:
- X group_overview(-1);
- X goto redraw;
- X
- X case K_KILL_HANDLING:
- X switch (kill_menu(ah)) {
- X case 0:
- X more_return(MC_DO_SELECT);
- X case 1:
- X more_return(MC_DO_KILL);
- X default:
- X break;
- X }
- X goto Prompt;
- X
- X case K_READ_GROUP_UPDATE:
- X if (mode & MM_PREVIEW) more_return(MC_MENU);
- X prompt("Mark rest of current group as read?");
- X if (yes(1) <= 0) goto Prompt;
- X more_return(MC_READGROUP);
- X
- X case K_NEXT_GROUP_NO_UPDATE:
- X if (mode & MM_PREVIEW) more_return(MC_MENU);
- X more_return(MC_NEXTGROUP);
- X
- X case K_BACK_TO_MENU:
- X more_return(MC_MENU);
- X
- X case K_PREVIOUS:
- X if ((mode & MM_PREVIOUS) == 0) {
- X msg("No previous article");
- X goto dflt_prompt;
- X }
- X more_return(MC_PREV);
- X
- X case K_ADVANCE_GROUP:
- X case K_BACK_GROUP:
- X case K_GOTO_GROUP:
- X news_save = news;
- X digest_save = digest;
- X more_cmd = goto_group(c, ah, (flag_type)0);
- X news = news_save;
- X digest = digest_save;
- X
- X switch (more_cmd) {
- X case ME_NO_REDRAW:
- X goto Prompt;
- X
- X case ME_QUIT:
- X more_return( ME_QUIT );
- X
- X default:
- X goto redraw;
- X }
- X
- X case K_NEXT_LINE:
- X if (eof) break;
- X if (screen_offset) goto same_prompt;
- X
- X print_lines = 1;
- X goto scroll;
- X
- X case K_NEXT_HALF_PAGE:
- X if (eof) break;
- X if (screen_offset) goto same_prompt;
- X
- X print_lines = window_lines/2;
- X
- X scroll:
- X gotoxy(0, prompt_line);
- X clrpage(prompt_line);
- X no_raw();
- X
- X if (print_lines + lno < (Lines - 1))
- X goto next_page;
- X
- X stop_line = -1;
- X gotoxy(0, Lines-1);
- X c = print_lines + lno - Lines + 2;
- X while (--c >= 0) {
- X putchar(NL);
- X if (--lno1 < 0) topline++;
- X prompt_line--;
- X }
- X if (lno1 < 0) lno1 = 0;
- X if (prompt_line < 0) prompt_line = 0;
- X lno = prompt_line;
- X goto next_line;
- X
- X case K_PREV_HALF_PAGE:
- X if (topline <= 1) goto Prompt;
- X linenum = topline - window_lines/2;
- X if (linenum < 1) linenum = 1;
- X goto next_page;
- X
- X case K_PREV_PAGE:
- X if (topline <= 1) goto Prompt;
- X linenum = topline - window_lines + overlap; /* not perfect after FF */
- X underline_line = topline;
- X if (linenum < 1) linenum = 1;
- X goto next_page;
- X
- X case K_SKIP_LINES:
- X skip_char = linebuf[0];
- X goto next_page;
- X
- X case K_GOTO_LINE:
- X prompt("\1Go to line:\1 ");
- X if ((fname = get_s(NONE, NONE, "$^", NULL_FCT)) == NULL)
- X goto Prompt;
- X
- X if (*fname == NUL) {
- X if (prev_goto < 0) goto Prompt;
- X goto_line = prev_goto;
- X
- X } else
- X if (*fname == '$')
- X goto_line = 30000;
- X else
- X if (*fname == '^')
- X goto_line = 1;
- X else {
- X goto_line = atoi(fname);
- X if (goto_line <= 0) {
- X goto_line = -1;
- X goto Prompt;
- X }
- X }
- X
- X goto_page:
- X prev_goto = topline;
- X
- X if (goto_line <= maxline) {
- X linenum = goto_line;
- X goto_line = -1;
- X }
- X
- X goto next_page;
- X
- X case K_SELECT_SUBJECT:
- X more_return(MC_ALLSUBJ);
- X
- X case K_HEADER_PAGE:
- X fseek(art, linepos[0], 0);
- X goto_line = 0;
- X goto goto_page;
- X
- X case K_FIRST_PAGE:
- X goto_line = 1;
- X goto goto_page;
- X
- X case K_LAST_PAGE:
- X goto_line = 30000;
- X goto goto_page;
- X
- X case K_GOTO_MATCH:
- X prompt("\1/\1");
- X if ((fname = get_s(NONE, NONE, "/", NULL_FCT)) == NULL)
- X goto Prompt;
- X
- X if (*fname && *fname != '/') {
- X if (regular_expr) freeobj(regular_expr);
- X if (case_fold_search) fold_string(fname);
- X regular_expr = regcomp(fname);
- X }
- X
- X case K_NEXT_MATCH:
- X if (regular_expr == NULL) {
- X msg("No previous expression");
- X goto Prompt;
- X }
- X
- X match_expr = 1;
- X if (match_topline != topline) prev_goto = topline;
- X match_topline = topline;
- X match_botline = linenum;
- X if (match_lines == 0 && topline <= 1) linenum = topline;
- X match_lines = 0;
- X goto next_line; /* don't clear the screen if no match */
- X
- X case K_FULL_DIGEST:
- X if (mode & MM_DIGEST)
- X more_return( MC_NO_REDRAW );
- X
- X if (!in_digest)
- X goto same_prompt;
- X
- X /* could do something more clever here later */
- X digestah = *ah;
- X digestah.flag &= ~A_DIGEST;
- X digestah.hpos = digestah.fpos = 0;
- X fseek(art, 0L, 2);
- X digestah.lpos = ftell(art);
- X
- X switch (more(&digestah, mode | MM_DIGEST, screen_offset)) {
- X
- X case MC_REDRAW:
- X goto redraw;
- X
- X case MC_NO_REDRAW:
- X goto safe_redraw;
- X
- X case MC_QUIT:
- X more_return( MC_QUIT );
- X
- X case MC_REENTER_GROUP:
- X more_return( MC_REENTER_GROUP );
- X
- X default:
- X goto safe_redraw;
- X }
- X
- X case K_LEAVE_NEXT:
- X ah->attr = A_LEAVE_NEXT;
- X more_return(MC_PREVIEW_NEXT);
- X
- X case K_LEAVE_ARTICLE:
- X ah->attr = (mode & MM_PREVIEW) ? A_SELECT : A_LEAVE;
- X /* fall thru */
- X
- X case K_NEXT_ARTICLE:
- X if ((mode & MM_PREVIEW) == 0) break;
- X more_return(MC_PREVIEW_NEXT);
- X
- X case K_BACK_ARTICLE:
- X if (mode & MM_FIRST_ARTICLE) {
- X msg("First article is displayed");
- X goto same_prompt;
- X }
- X more_return(MC_BACK_ART);
- X
- X case K_FORW_ARTICLE:
- X if (mode & MM_LAST_ARTICLE) {
- X msg("Last article is displayed");
- X goto same_prompt;
- X }
- X more_return(MC_FORW_ART);
- X
- X case K_NEXT_SUBJECT:
- X more_return(MC_NEXTSUBJ);
- X
- X case K_ROT13:
- X if (rot13_must_init) {
- X register i;
- X for (i=0; i<=127; i++) {
- X c = i;
- X if (c >= 'a' && c <= 'm') c += 13;
- X else if (c >= 'n' && c <= 'z') c -= 13;
- X else if (c >= 'A' && c <= 'M') c += 13;
- X else if (c >= 'N' && c <= 'Z') c -= 13;
- X rot13_table[i] = c;
- X }
- X rot13_must_init = 0;
- X }
- X
- X rot13_active = !rot13_active;
- X goto safe_redraw;
- X
- X case K_COMPRESS:
- X compress_space = !compress_space;
- X goto safe_redraw;
- X
- X case K_PREVIEW:
- X if (mode & MM_PREVIEW)
- X more_return(MC_PREVIEW_OTHER);
- X
- X /* fall thru to "default" */
- X
- X default:
- X msg("Command %d not supported", c);
- X goto dflt_prompt;
- X }
- X
- X more_return(MC_NEXT);
- X
- X more_exit:
- X in_menu_mode = o_mode;
- X rot13_active = 0;
- X
- X if (linepos != lineposbuf) freeobj(linepos);
- X
- X no_raw();
- X fclose(art);
- X
- X if (mode & MM_PREVIEW)
- X if (more_cmd != MC_QUIT && more_cmd != MC_REENTER_GROUP) {
- X gotoxy(0, screen_offset);
- X clrpage(screen_offset);
- X if (auto_preview_mode && ah->attr == 0)
- X ah->attr = A_READ;
- X if (screen_offset == 0) prompt_line = -1;
- X }
- X
- X return more_cmd;
- X}
- X
- X
- Xrot13_line(cp)
- Xregister char *cp;
- X{
- X register int c;
- X
- X while (c = *cp)
- X *cp++ = ROT13_DECODE(c);
- X}
- X
- END_OF_FILE
- if test 24124 -ne `wc -c <'more.c'`; then
- echo shar: \"'more.c'\" unpacked with wrong size!
- fi
- # end of 'more.c'
- fi
- echo shar: End of archive 9 \(of 22\).
- cp /dev/null ark9isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 22 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
-
- exit 0 # Just in case...
-